<template>
  <div>
    <div style="margin-top: 20px">
      <el-collapse-transition>
        <div v-show="isShow" style="height:auto">
          <el-container>
            <el-main>
              <div class="tag-row">
                <el-tag v-for="(item, index) in labelList" :key="index" effect="plain" class="tag-item"
                  @click="handleTagClick()">
                  <!-- 处理后续跳转 -->
                  <div class="tagname">{{ item.labelTitle }} <span class="tagcount">{{ item.subjectCount }}</span>
                  </div>
                </el-tag>
              </div>
            </el-main>
          </el-container>
        </div>
      </el-collapse-transition>
      <el-button @click="isShow = !isShow" class="collapsebutton">
        <span>{{ isShow ? '收起' : '展开' }} 
          <DCaret style="width: 16px;" />
        </span>
        <el-icon :size="20">
        </el-icon>
      </el-button>
    </div>
    <!-- 下拉框分类题目 -->
    <div class="flex flex-wrap gap-4 items-center selectitem">
      <el-select v-model="queryCondition.difficult" placeholder="难度" size="large" style="flex: 1;"
        class="selectclassifity">
        <el-option v-for="item in OjSubjectDifficultOptions" :key="item.value" :label="item.label"
          :value="item.value" />
      </el-select>
      <el-select v-model="_" placeholder="状态" size="large" style="flex: 1;" class="selectclassifity">
        <el-option v-for="item in OjSubjectStatusOptions" :key="item.value" :label="item.label" :value="item.value" />
      </el-select>
      <el-input v-model="SearchText" style="flex: 3; height: 40px;" placeholder="搜索题目、编号或内容" :prefix-icon="Search" />
      <el-button round class="questionclassification" @click="randomSubject()"><svg t="1737185289623" class="icon"
          viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg&#34;"  p-id="9424" width="30" height="30">
          <path
            d="M880.2 634.1c-14.5-14.5-37.9-14.5-52.4 0s-14.5 37.9 0 52.4l85 85h-66.2-0.1c-78.3 0-151.6-34.9-201-95.6L512.6 512l133.1-163.8c49.4-60.8 122.6-95.6 201-95.6h66.1l-84.8 85c-14.5 14.5-14.5 37.9 0 52.4 7.2 7.2 16.7 10.8 26.2 10.8s19-3.6 26.2-10.9L1001.1 269l4.2-4.3c12.1-13.6 18.8-31 18.7-49.4 0-19.8-7.8-38.4-21.8-52.3l-122-122c-14.5-14.5-37.9-14.5-52.4 0s-14.5 37.9 0 52.4l85 85h-66.2-0.1c-100.7 0-195 44.8-258.5 123L464.8 453.2 341.6 301.5C278 223.3 183.7 178.4 82.9 178.4H37.1C16.6 178.4 0 195 0 215.5s16.6 37.1 37.1 37.1h45.8c78.4 0 151.7 34.9 201.2 95.8l133 163.7-133 163.7c-49.4 60.9-122.8 95.8-201.2 95.8H37.1C16.6 771.5 0 788.1 0 808.5c0 20.5 16.6 37.1 37.1 37.1h45.8c100.8 0 195.1-44.9 258.7-123.1l123.2-151.7 123.3 151.8c63.5 78.2 157.7 123 258.5 123H912.8l-84.9 85c-14.5 14.5-14.5 38 0 52.4 7.2 7.2 16.7 10.9 26.2 10.9s19-3.6 26.2-10.9l122.1-122.2c28.9-29 28.8-76-0.1-104.8L880.2 634.1z"
            fill="#27D0D8" p-id="9425"></path>
        </svg><span class="questionname">随机一题</span></el-button>
    </div>
    <!-- 表格区域 -->
    <div class="questionitem">
      <el-table :data="subjectList" style="width: 100%" @row-click="handleRowClick">
        <el-table-column prop="textStatus" label="状态" />
        <el-table-column prop="subjectTitle" label="题目" />
        <el-table-column prop="passRate" label="通过率" />
        <el-table-column prop="difficult" label="难度" />
      </el-table>
    </div>
    <!-- 分页组件 -->
    <div class="pagination">
      <el-pagination
        background
        layout="total, sizes, prev, pager, next, jumper"
        :total="total"
        :page-size="queryCondition.pageSize"
        :current-page="queryCondition.currentPage"
        @current-change="handleCurrentChange"
      />
    </div>
    <!-- 新增题目按钮 -->
    <el-button type="success" class="add-subject" @click="jumpToAddSubject()">新增题目</el-button>
  </div>
</template>

<script lang="ts" setup>
import { onMounted, ref, watchEffect } from 'vue';
import { ElContainer, ElMain, ElTag, type TableColumnCtx, ElButton } from 'element-plus';
import { Search } from '@element-plus/icons-vue';
import { subjectApi, tagApi } from '@/request';
import type { ojLable } from '@/typedefined/Label';
import type { OjSubjectQueryCondition } from '@/typedefined/QueryCondition';
import { OjSubjectDifficultOptions, OjSubjectStatusOptions, OjSubjectStatusTextIconEnum, getOjSubjectDifficultEnumByCode } from '@/common/OjConstant';
import type { SubjectPage } from '@/typedefined/Page';
import type { OjSubject } from '@/typedefined/Subject';
import { BusinessException } from '@/exception/BusinessException';
import { canConvertToInteger, debounce } from '@/utils/CommonUtils';
import { illegalArgumentsException } from '@/exception/illegalArgumentsException';
import { useOjStores } from '@/stores/ojStores';
import { storeToRefs } from 'pinia';
import router from '@/router';
import { PageConstant } from '@/common/Constant';
import { useUserStore } from '@/stores/userStores';

const userStores = useUserStore();
// 用户信息
const { userInfo } = storeToRefs(userStores);

const ojStores = useOjStores();
// 共享题目列表，当前题目信息
const { ojSubjectList, currentSubject } = storeToRefs(ojStores);

// 变量控制标签渲染组件的展示与隐藏
const isShow = ref<boolean>(true);

// 标签列表
const labelList = ref<Array<ojLable>>([]);

// 搜索文本
const SearchText = ref<string>("");

// 临时占位符变量
const _ = ref<any>();

// 表格数据的类型定义
type tableDataType = {
  id: number, // 题目id（编号）
  subjectTitle: string, // 题目标题
  passRate: string, // 通过率
  difficult: string, // 题目难度
  textStatus: string // 题目图标状态
};

// 题目列表
const subjectList = ref<Array<tableDataType>>([]);

// 题目查询条件
const queryCondition = ref<OjSubjectQueryCondition>({
  currentPage: 1,
  pageSize: 20,
  difficult: null as unknown as number
});

// 总条数
const total = ref(0);

// 组件创建完毕执行的声明周期钩子函数
onMounted(async () => {
  try {
    // 请求标签列表
    const dataLabelList = await tagApi.getojTag() as unknown as Array<ojLable>;
    // 切换数据源
    labelList.value = dataLabelList;
    // 默认题目列表请求
    const dataSubjectPage = await defaultGetSubjectList() as unknown as SubjectPage<OjSubject>;
    // 设置总条数
    total.value = dataSubjectPage.total;
    // 共享数据注入
    ojSubjectList.value = dataSubjectPage.records;
    // 类型转换
    const dataSubjectList = OjSubjectList2tableDataTypeList(dataSubjectPage.records);
    // 切换数据源
    subjectList.value = [...subjectList.value, ...dataSubjectList];
  }
  catch (e) {
    throw new BusinessException("请求标签列表失败");
  }
});

// 默认分页查询
async function defaultGetSubjectList() {
  return subjectApi.oj.defaultQuerySubjectList(queryCondition.value);
}

// 重置题目列表
function resetSubjectList() {
  subjectList.value = [];
  ojSubjectList.value = [];
}

// 监听下拉框的变化
watchEffect(() => {
  if (queryCondition.value.difficult) {
    // 重置题目列表
    resetSubjectList();
    // 请求对应的题目
    getSubjectList(queryCondition.value);
  }
});

// 获取题目列表
async function getSubjectList(queryCondition: OjSubjectQueryCondition) {
  try {
    // 请求接口，获取分页题目列表（题目的全信息）
    const dataPageList: SubjectPage<OjSubject> = await subjectApi.oj.getSubjectList(queryCondition) as unknown as SubjectPage<OjSubject>;
    // 设置总条数
    total.value = dataPageList.total;
    // 题目列表缓存
    ojSubjectList.value = [...ojSubjectList.value, ...dataPageList.records];
    // 类型转换
    const addList: Array<tableDataType> = OjSubjectList2tableDataTypeList(dataPageList.records);
    // 添加进原题目列表
    subjectList.value = [...subjectList.value, ...addList];
  }
  catch (e) {
    throw new BusinessException("题目列表获取失败");
  }
}

// 类型转换工具 => OjSubject列表 to tableDataType列表
function OjSubjectList2tableDataTypeList(originList: Array<OjSubject>): Array<tableDataType> {
  if (!originList) throw new illegalArgumentsException("originList不能为空");
  return originList.map((item: OjSubject) => {
    return {
      id: item.id, // 题目编号（id）
      subjectTitle: item.id + ". " + item.subjectTitle, // 题目标题
      passRate: item.submitCount ? (item.acceptCount / item.submitCount * 100).toFixed(2) + "%" : "暂无提交", // 通过率
      difficult: getOjSubjectDifficultEnumByCode(item.difficult).description, // 题目难度
      textStatus: OjSubjectStatusTextIconEnum.NOT_STARTED // 题目图标状态
    }
  });
}

// 获取题目列表的防抖封装
const getSubjectListDeBounce = debounce(async (queryCondition: OjSubjectQueryCondition) => {
  // 重置题目列表
  resetSubjectList();
  // 请求题目列表
  await getSubjectList(queryCondition);
}, 1000);

// 监听搜索框内容的变换
watchEffect(() => {
  if (SearchText.value) {
    // 用户输入的数字能够符合id搜索
    if (canConvertToInteger(SearchText.value)) {
      const id = parseInt(SearchText.value);
      if (id > 0) {
        queryCondition.value.id = id;
      }
    }
    // 包含题目标题字段搜索
    queryCondition.value.subjectTitle = SearchText.value;
    // 包含题目内容详情搜索
    queryCondition.value.detailDescription = SearchText.value;
    getSubjectListDeBounce(queryCondition.value);
  }
});

// 标签点击处理函数
function handleTagClick() {
  alert(1);
}

// 表格行点击处理函数
function handleRowClick(row: tableDataType, _: TableColumnCtx<tableDataType>, __: MouseEvent) {
  currentSubject.value = ojSubjectList.value.find(item => item.id === row.id);
  router.push(PageConstant.ojSubmitPage + "/" + row.id);
}

// 随机一题
async function randomSubject() {
  const dataSubject = await subjectApi.oj.randomSubject() as unknown as OjSubject;
  console.warn(dataSubject);
}

// 新增题目页面跳转
function jumpToAddSubject() {
  const permission = userInfo.value.permissionList.find(item => item === "oj:add");
  if (!permission) throw new BusinessException("用户无权限");
  return router.push(PageConstant.ojAddSubjectPage);
}

// 处理当前页变化
function handleCurrentChange(newPage: number) {
  queryCondition.value.currentPage = newPage;
  getSubjectList(queryCondition.value);
}
</script>

<style scoped>
.transition-box {
  margin-bottom: 10px;
  width: 200px;
  height: 100px;
  border-radius: 4px;
  background-color: #409eff;
  text-align: center;
  color: #fff;
  padding: 40px 20px;
  box-sizing: border-box;
  margin-right: 20px;
}

.tag-row {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}

.tag-item {
  cursor: pointer;
  border-radius: 16px;
  padding: 0 10px;
  height: 32px;
  line-height: 32px;
  background-color: white;
  border: none;
  font-size: 16px;

  &:hover {
    /* color: #ff6b00; */
    background-color: #fff3e8;
    color: #409eff;
  }
}

.tagname {
  color: black;

}

.tagcount {
  margin-left: 5px;
  padding: 3px 7px;
  background-color: rgb(242, 243, 244);
  color: rgba(71, 68, 68, 0.699);
  border-radius: 12px;
}

.collapsebutton {
  margin-right: 50px;
  margin-bottom: 35px;
  float: right;
}

.classification {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
}

.questionclassification {
  background-color: rgb(242, 243, 244);
  flex: 1;
  margin: 0 60px;
  text-align: center;
  height: 45px;

}

.questionname {
  font-size: 20px;
  font-weight: bold;
  margin-left: 10px;
}

.selectitem {
  margin-top: 20px;
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
}

.selectclassifity {
  flex: 1;
  margin: 0 60px;
  text-align: center;
  height: 45px;
}

.questionitem {
  margin: 50px 50px;
}

/* 添加悬停光标效果 */
::v-deep .el-table__body tr:hover>td {
  cursor: pointer;
  /* 如果需要可以同时添加背景色变化 */
  background-color: #f5f7fa !important;
  user-select: none;
}

.add-subject {
  position: fixed;
  /* 固定定位 */
  left: 0;
  /* 距离左侧 0px */
  top: 50%;
  /* 距离顶部 50% */
  transform: translateY(-50%);
  /* 向上偏移自身高度的 50%，实现垂直居中 */
  z-index: 1000;
  /* 确保按钮在其他内容之上 */
  width: 30px;
  height: 100px;
  white-space: normal;
  /* 允许文字换行 */
  word-wrap: break-word;
  /* 允许在单词内换行 */
  word-break: break-all;
  /* 强制换行 */
  text-align: center;
  /* 文字居中对齐 */
  letter-spacing: 2px;
  /* 增加文字间的间距 */
  padding: 10px;
  /* 调整内边距 */
  line-height: 1.5;
  /* 调整行高 */
}
</style>
